use std::fmt::format;
use std::sync::{Arc, mpsc, Mutex};
use std::thread;
use std::time::Duration;


fn main() {
    // println!("Hello, world!");


    let handler = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number is {} , from spawn  thread !", i);

            thread::sleep(Duration::from_millis(1));
        }
    });


    for i in 1..5 {
        println!("hi number is {} , from main  thread !", i);

        thread::sleep(Duration::from_millis(1));
    }


    // main 线程结束， 结束


    // 这个方法会让main 等 子线程 执行完了 ， 再往下执行
    handler.join().unwrap();
}


#[test]
fn test_move() {

    // move  关键字  ， 在线程中获取线程外部的数据
    let list = vec![1, 2, 3];
    let handler = thread::spawn(move || {
        for i in 0..3 {
            println!("index  is {} , vec[] is {} , from spawn  thread !", i, list[i]);

            thread::sleep(Duration::from_millis(1));
        }
    });


    handler.join().unwrap();
}


//    channel 实现并发
#[test]
fn test_msg() {
    let (tx, rx) = mpsc::channel();


    //创建多个发送者
    let tx2 = mpsc::Sender::clone(&tx);

    let th1 = thread::spawn(move || {
        for i in 1..10 {
            let val = format!("thread is tx1 , hello {}", i);

            // 发送消息
            tx.send(val).unwrap();

            thread::sleep(Duration::from_millis(200));
        }
    });


    let th3 = thread::spawn(move || {
        for i in 1..10 {
            let val = format!("thread is tx2 , hello {}", i);

            // 发送消息
            tx2.send(val).unwrap();

            thread::sleep(Duration::from_millis(200));
        }
    });


    let th2 = thread::spawn(move || {


        // 类似迭代器
        for msg in rx {
            println!("msg is : 【{}】", msg);
        }
    });


    th1.join().unwrap();
    th3.join().unwrap();
    th2.join().unwrap();


    println!("end ...")
}


// 共享内存实现并发 (Mutex)

#[test]
fn test_mutex() {


    // mutex 2调规则
    // 1. 使用数据前 必须获取锁
    // 2. 使用完mutex保护的数据后， 必须对数据解锁


    // mutex 有死锁的风险

    let m = Mutex::new(10);

    {
        let mut num = m.lock().unwrap();

        *num += 1;
        //  离开结构体  自动解锁
    }


    println!("num is {:?}", m);
}


#[test]
fn test_mutex2() {
    let counter = Arc::new(Mutex::new(0));


    let mut handlers = vec![];
    for index in 0..100 {
        let counter = Arc::clone(&counter);
        let thread = thread::spawn(move || {
            let mut count = counter.lock().unwrap();

            *count += 1;
        });

        handlers.push(thread);
    }


    for hand in handlers {
        hand.join().unwrap();
    }

    println!("count is {:?}", counter);
}



